<template>
  <div class="recycle-container" ref="container" @scroll="setPool">
    <div class="warpper" :style="{ height: `${totalSize}px` }">
      <div
        class="warpper-item"
        v-for="r in pool"
        :key="r.item[keyFiled]"
        :style="{ transform: `translateY(${r.position}px)` }"
      >
        <slot :item="r.item"></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    items: Array,
    itemSize: {
      type: Number,
      default: 0,
    },
    keyFiled: {
      // items数组中，每个对象那个属性代表唯一且稳定的编号
      type: String,
      default: "id",
    },
  },
  data: () => ({
    //  {item:原始数据,position:该数据对应的偏移位置}
    pool: [], // 渲染池，保存当前需要渲染的数据
    prev: 10,
    next: 10,
  }),
  computed: {
    totalSize() {
      return this.items.length * this.itemSize;
    },
  },
  mounted() {
    this.setPool();
  },
  methods: {
    setPool() {
      const scrollTop = this.$refs.container.scrollTop;
      const h = this.$refs.container.clientHeight;
      let startIndex = Math.floor(scrollTop / this.itemSize), // 上方不可见的数据条数,
        endIndex = Math.ceil((scrollTop + h) / this.itemSize),
        startPosition = startIndex * this.itemSize;
      // 可以多显示一些数据
      startIndex -= this.prev;
      startIndex = startIndex <= 0 ? 0 : startIndex;
      endIndex += this.next;
      this.pool = this.items.slice(startIndex, endIndex).map((item, i) => ({
        item,
        position: i * this.itemSize + startPosition,
      }));
    },
  },
};
</script>

<style scoped>
.recycle-container {
}
.warpper {
  position: relative;
}
.warpper-item {
  position: absolute;
  top: 0;
  left: 0;
}
</style>
